package com.project.m.api.busi.handlers.hicatcard.wx;

import com.alibaba.fastjson.JSON;
import com.project.m.api.busi.bean.ext.AuthCodeToOpenIdReq;
import com.project.m.api.busi.bean.ext.AuthCodeToOpenIdResp;
import com.project.m.api.busi.bean.wx.WxAuthResp;
import com.project.m.api.busi.config.BusiError;
import com.project.m.api.busi.db.entity.hicatcard.distributor.TDistributor;
import com.project.m.api.busi.db.entity.hicatcard.distributor.TDistributorPerson;
import com.project.m.api.busi.db.entity.hicatcard.user.TUser;
import com.project.m.api.busi.db.service.hicatcard.distributor.DistributorPersonService;
import com.project.m.api.busi.db.service.hicatcard.distributor.DistributorService;
import com.project.m.api.busi.db.service.hicatcard.user.UserService;
import com.project.m.api.busi.handlers.DefaultBizParamChecker;
import com.project.m.api.busi.util.CommonConvertor;
import com.project.m.api.busi.util.HttpRequestUtil;
import com.project.m.api.busi.util.SLEmojiFilter;
import com.project.m.api.busi.util.TimeUtil;
import com.project.m.api.common.biz.BizHandler;
import com.project.m.api.validates.ValidateParam;
import com.project.m.api.validates.ValidateRet;
import com.project.m.api.validates.ValidateType;
import com.project.m.api.validates.ValidateUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 1-通过wx.login中的code来获取openid
 * 2-req参数中有openid的，直接更新用户信息
 */
@Component
public class AuthCodeToOpenIdBizHandler extends DefaultBizParamChecker<AuthCodeToOpenIdReq, AuthCodeToOpenIdResp> implements BizHandler<AuthCodeToOpenIdReq, AuthCodeToOpenIdResp> {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Value("${weixin.miniapp.appid}")
    private String appid;

    @Value("${weixin.miniapp.secret}")
    private String secret;

    @Autowired
    UserService userService;

    @Autowired
    DistributorService distributorService;

    @Autowired
    DistributorPersonService distributorPersonService;

    @Override
    public AuthCodeToOpenIdResp handle(AuthCodeToOpenIdReq bizRequest) throws Exception {
        //先进行emoji表情过滤
        String filterEmojiJson = SLEmojiFilter.filterEmoji(JSON.toJSONString(bizRequest));
        bizRequest = JSON.parseObject(filterEmojiJson, AuthCodeToOpenIdReq.class);
        logger.info("filterEmojiJson:" + JSON.toJSONString(bizRequest));

        AuthCodeToOpenIdResp bizResp = new AuthCodeToOpenIdResp();
        ValidateRet vRet = checkParam(bizRequest, bizResp);
        if (!vRet.isValid()) {
            return bizResp;
        }

        if (StringUtils.isEmpty(bizRequest.getCode())) {
            updateOrCreateUserInfo(bizRequest, bizResp, bizRequest.getOpenid());
            bizResp.setWxAuthOpenid(bizRequest.getOpenid());
//			bizResp.setSession_key("");
            return bizResp;
        } else {
            String jsonResp = HttpRequestUtil.getRequest("https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret=" + secret + "&js_code=" + bizRequest.getCode() + "&grant_type=authorization_code");
            WxAuthResp wxAuthResp = JSON.parseObject(jsonResp, WxAuthResp.class);
            if (wxAuthResp.getOpenid() != null && wxAuthResp.getOpenid().length() > 0) {
                bizResp.setWxAuthOpenid(wxAuthResp.getOpenid());
                bizResp.setSession_key(wxAuthResp.getSession_key());
                updateOrCreateUserInfo(bizRequest, bizResp, wxAuthResp.getOpenid());
                return bizResp;
            } else {
                bizResp.setResult_code(BusiError.ERR_CODE_WX_AUTH);
                bizResp.setError_message(BusiError.ERR_MSG_WX_AUTH);
                return bizResp;
            }
        }

    }

    private void updateOrCreateUserInfo(AuthCodeToOpenIdReq bizRequest, AuthCodeToOpenIdResp bizResp, String openId) {
        TUser userInfo = null;
        try {
            List<TUser> userList = userService.findByOpenidAndEnable(openId, true);
            if (userList == null || userList.size() == 0) {
                //新增
                TUser user = new TUser();
                if (!StringUtils.isEmpty(bizRequest.getPhone())) {
                    user.setPhone(bizRequest.getPhone());
                }
                //user.setPhone(bizRequest.getPhone());
//					String str = SLEmojiFilter.filterEmoji(bizRequest.getNickName());
                user.setNickname(bizRequest.getNickName());
                user.setAvaterUrl(bizRequest.getAvaterUrl());
                if (!StringUtils.isEmpty(bizRequest.getGender())) {
                    user.setGender(Integer.valueOf(bizRequest.getGender()));
                }
                user.setCountry(CommonConvertor.convertStringAvoidNull(bizRequest.getCountry()));
                user.setProvince(CommonConvertor.convertStringAvoidNull(bizRequest.getProvince()));
                user.setCity(CommonConvertor.convertStringAvoidNull(bizRequest.getCity()));
                user.setLanguage(CommonConvertor.convertStringAvoidNull(bizRequest.getLanguage()));
                user.setOpenid(CommonConvertor.convertStringAvoidNull(openId));
                user.setUnionid("");
                user.setCreateTime(TimeUtil.getCurrTime());
                user.setUpdateTime(TimeUtil.getCurrTime());
                user.setEnable(true);
                user.setStatus(TUser.STATUS_IN_USE);
                userService.saveUser(user);
                userInfo = user;
            } else {
                //列表更新 - 只保留第一个，其他全部置为false
                for (TUser user : userList) {
                    if (bizRequest.getPhone() != null && bizRequest.getPhone().length() > 0) {
                        user.setPhone(bizRequest.getPhone());
                    }
//						String str = SLEmojiFilter.filterEmoji(bizRequest.getNickName());
                    user.setNickname(bizRequest.getNickName());
//						user.setNickname(bizRequest.getNickName());
                    user.setAvaterUrl(bizRequest.getAvaterUrl());
                    if (StringUtils.isNotBlank(bizRequest.getGender())) {
                        user.setGender(Integer.valueOf(bizRequest.getGender()));
                    }
                    user.setCountry(CommonConvertor.convertStringAvoidNull(bizRequest.getCountry()));
                    user.setProvince(CommonConvertor.convertStringAvoidNull(bizRequest.getProvince()));
                    user.setCity(CommonConvertor.convertStringAvoidNull(bizRequest.getCity()));
                    user.setLanguage(CommonConvertor.convertStringAvoidNull(bizRequest.getLanguage()));
                    user.setUpdateTime(TimeUtil.getCurrTime());
                    user.setEnable(false);
                    userInfo = user;
                }
                userList.get(0).setEnable(true);
                userService.saveUserList(userList);
            }


            //判断distributor是否存在

            //查用户当前distributor是渠道还是分销

            //原来是渠道商 - 替换

            //原来是分销 - 有效期、保护期判断

            //TDistributorPerson记录所属于distributor，以及扫码进入的distributor

            boolean hasNewDistributor = false;
            TDistributor distributor = null;
            if (!StringUtils.isEmpty(bizRequest.getDistributorNumber())) {
                //分销商是否存在
                List<TDistributor> distributorList = distributorService.findByDistributorNumberAndEnable(bizRequest.getDistributorNumber(), true);
                if (!CollectionUtils.isEmpty(distributorList)) {
                    distributor = distributorList.get(0);
                    hasNewDistributor = true;
                }
            }

            Long originDistributorId = -1l;
            if (userInfo.getDistributorId() != null) {
                originDistributorId = userInfo.getDistributorId();
            }

            TDistributor originDistributor = null;
            //扫渠道码进入
            if (hasNewDistributor) {

                if (originDistributorId > 0) {
                    originDistributor = distributorService.findByDistributorId(originDistributorId);
                }

                if (originDistributor == null) {
                    //原来无渠道

                    //添加渠道，记录
                    //记录distributor id 和时间
                    if (distributor.getStatus().equalsIgnoreCase(TDistributor.STATUS_SHOW)){
                        userInfo.setDistributorId(distributor.getDistributorId());
                        userInfo.setDistributorTime(TimeUtil.getCurrTime());
                        userInfo.setUpdateTime(TimeUtil.getCurrTime());
                    }


                    TDistributorPerson distributorPerson = new TDistributorPerson();
                    if (distributor.getStatus().equalsIgnoreCase(TDistributor.STATUS_SHOW)) {
                        distributorPerson.setDistributorId(distributor.getDistributorId());
                        if (distributor.getType().equalsIgnoreCase(TDistributor.TYPE_DISTRIBUTOR)) {
                            distributorPerson.setProtectEndTime(TimeUtil.getXDayLater(TimeUtil.DATE_PATTERN_NOSEPARTOR, distributor.getProtectDay()));
                        } else {
                            distributorPerson.setProtectEndTime("");
                        }
                    }
                    else {
                        distributorPerson.setDistributorId(-1l);
                        distributorPerson.setProtectEndTime("");
                    }


                    distributorPerson.setUserId(userInfo.getUserId());
                    distributorPerson.setLoginFlag(distributor.getDistributorId());
                    distributorPerson.setCreateTime(TimeUtil.getCurrTime());
                    distributorPerson.setUpdateTime(TimeUtil.getCurrTime());

                    distributor.setTotalTimes(distributor.getTotalTimes() + 1);
                    distributor.setUpdateTime(TimeUtil.getCurrTime());

                    userService.saveUser(userInfo);
                    distributorService.saveDistributor(distributor);
                    distributorPersonService.saveDistributorPerson(distributorPerson);
                } else {
                    //有渠道

                    boolean isChange = true;
                    if (originDistributor.getType().equalsIgnoreCase(TDistributor.TYPE_DISTRIBUTOR)) {
                        if (userInfo.getDistributorTime().compareToIgnoreCase(TimeUtil.getXDayLater(TimeUtil.DATE_PATTERN_NOSEPARTOR, 0 - originDistributor.getProtectDay())) > 0) {
                            isChange = false;
                        }
                    }

                    if (isChange) {

                        //变化 - 判断新渠道是否有效 - 有效，记录。无效，置空
                        if (distributor.getStatus().equalsIgnoreCase(TDistributor.STATUS_SHOW)) {
                            //添加渠道，记录
                            //记录distributor id 和时间
                            userInfo.setDistributorId(distributor.getDistributorId());
                            userInfo.setDistributorTime(TimeUtil.getCurrTime());
                            userInfo.setUpdateTime(TimeUtil.getCurrTime());

                            TDistributorPerson distributorPerson = new TDistributorPerson();
                            distributorPerson.setDistributorId(distributor.getDistributorId());
                            if (distributor.getType().equalsIgnoreCase(TDistributor.TYPE_DISTRIBUTOR)) {
                                distributorPerson.setProtectEndTime(TimeUtil.getXDayLater(TimeUtil.DATE_PATTERN_NOSEPARTOR, distributor.getProtectDay()));
                            } else {
                                distributorPerson.setProtectEndTime("");
                            }

                            distributorPerson.setUserId(userInfo.getUserId());
                            distributorPerson.setLoginFlag(distributor.getDistributorId());
                            distributorPerson.setCreateTime(TimeUtil.getCurrTime());
                            distributorPerson.setUpdateTime(TimeUtil.getCurrTime());

                            distributor.setTotalTimes(distributor.getTotalTimes() + 1);
                            distributor.setUpdateTime(TimeUtil.getCurrTime());

                            originDistributor.setTotalTimes(originDistributor.getTotalTimes() - 1);
                            originDistributor.setUpdateTime(TimeUtil.getCurrTime());


                            userService.saveUser(userInfo);
                            distributorService.saveDistributor(distributor);
                            distributorService.saveDistributor(originDistributor);
                            distributorPersonService.saveDistributorPerson(distributorPerson);
                        }
                        else {
                            userInfo.setDistributorId(-1l);
                            userInfo.setDistributorTime("");
                            userInfo.setUpdateTime(TimeUtil.getCurrTime());

                            TDistributorPerson distributorPerson = new TDistributorPerson();
                            distributorPerson.setDistributorId(-1l);
                            distributorPerson.setProtectEndTime("");
                            distributorPerson.setUserId(userInfo.getUserId());
                            distributorPerson.setLoginFlag(distributor.getDistributorId());
                            distributorPerson.setCreateTime(TimeUtil.getCurrTime());
                            distributorPerson.setUpdateTime(TimeUtil.getCurrTime());


                            distributor.setTotalTimes(distributor.getTotalTimes() + 1);
                            distributor.setUpdateTime(TimeUtil.getCurrTime());


                            originDistributor.setTotalTimes(originDistributor.getTotalTimes() - 1);
                            originDistributor.setUpdateTime(TimeUtil.getCurrTime());

                            userService.saveUser(userInfo);
                            distributorService.saveDistributor(distributor);
                            distributorService.saveDistributor(originDistributor);
                            distributorPersonService.saveDistributorPerson(distributorPerson);
                        }



                    } else {
                        //不变

                        List<TDistributorPerson> distributorPersonList = distributorPersonService.findByUserIdAndEnableOrderByCreateTimeDesc(userInfo.getUserId(),true);
                        if(!CollectionUtils.isEmpty(distributorPersonList)){
                            TDistributorPerson distributorPerson = new TDistributorPerson();
                            distributorPerson.setDistributorId(distributorPersonList.get(0).getDistributorId());
                            distributorPerson.setUserId(userInfo.getUserId());
                            distributorPerson.setProtectEndTime(distributorPersonList.get(0).getProtectEndTime());
                            distributorPerson.setLoginFlag(distributor.getDistributorId());
                            distributorPerson.setCreateTime(TimeUtil.getCurrTime());
                            distributorPerson.setUpdateTime(TimeUtil.getCurrTime());
                            distributorPersonService.saveDistributorPerson(distributorPerson);
                        }
                    }
                }
            } else {
                //普通小程序进入

                if (originDistributorId > 0) {
                    originDistributor = distributorService.findByDistributorId(originDistributorId);
                    //判断是否过了有效期，过了就设置
                    boolean isChange = true;
                    if (originDistributor.getType().equalsIgnoreCase(TDistributor.TYPE_DISTRIBUTOR)) {
                        if (userInfo.getDistributorTime().compareToIgnoreCase(TimeUtil.getXDayLater(TimeUtil.DATE_PATTERN_NOSEPARTOR, 0 - originDistributor.getProtectDay())) > 0) {
                            isChange = false;
                        }
                        if (isChange) {
                            TDistributorPerson distributorPerson = new TDistributorPerson();
                            distributorPerson.setDistributorId(-1l);
                            distributorPerson.setUserId(userInfo.getUserId());
                            distributorPerson.setProtectEndTime("");
                            distributorPerson.setLoginFlag(-1l);
                            distributorPerson.setCreateTime(TimeUtil.getCurrTime());
                            distributorPerson.setUpdateTime(TimeUtil.getCurrTime());
                            distributorPersonService.saveDistributorPerson(distributorPerson);
                        }
                        else {
                            List<TDistributorPerson> distributorPersonList = distributorPersonService.findByUserIdAndEnableOrderByCreateTimeDesc(userInfo.getUserId(),true);
                            if(!CollectionUtils.isEmpty(distributorPersonList)){
                                TDistributorPerson distributorPerson = new TDistributorPerson();
                                distributorPerson.setDistributorId(distributorPersonList.get(0).getDistributorId());
                                distributorPerson.setUserId(userInfo.getUserId());
                                distributorPerson.setProtectEndTime(distributorPersonList.get(0).getProtectEndTime());
                                distributorPerson.setLoginFlag(-1l);
                                distributorPerson.setCreateTime(TimeUtil.getCurrTime());
                                distributorPerson.setUpdateTime(TimeUtil.getCurrTime());
                                distributorPersonService.saveDistributorPerson(distributorPerson);
                            }
                        }
                    }
                    else {
                        TDistributorPerson distributorPerson = new TDistributorPerson();
                        distributorPerson.setDistributorId(-1l);
                        distributorPerson.setUserId(userInfo.getUserId());
                        distributorPerson.setProtectEndTime("");
                        distributorPerson.setLoginFlag(-1l);
                        distributorPerson.setCreateTime(TimeUtil.getCurrTime());
                        distributorPerson.setUpdateTime(TimeUtil.getCurrTime());
                        distributorPersonService.saveDistributorPerson(distributorPerson);
                    }
                }



            }


//            if (!StringUtils.isEmpty(bizRequest.getDistributorNumber())) {
//                //分销商是否存在
//                List<TDistributor> distributorList = distributorService.findByDistributorNumberAndEnable(bizRequest.getDistributorNumber(), true);
//                if (!CollectionUtils.isEmpty(distributorList)) {
//                    TDistributor distributor = distributorList.get(0);
//                    //记录distributor id 和时间
//                    userInfo.setDistributorId(distributor.getDistributorId());
//                    userInfo.setDistributorTime(TimeUtil.getCurrTime());
//                    userInfo.setUpdateTime(TimeUtil.getCurrTime());
//
//                    TDistributorPerson distributorPerson = new TDistributorPerson();
//                    distributorPerson.setDistributorId(distributor.getDistributorId());
//                    distributorPerson.setUserId(userInfo.getUserId());
//                    distributorPerson.setCreateTime(TimeUtil.getCurrTime());
//                    distributorPerson.setUpdateTime(TimeUtil.getCurrTime());
//                    //logger.info("distributorPerson = " + JSON.toJSONString(distributorPerson) );
//
//                    distributor.setTotalTimes(distributor.getTotalTimes() + 1);
//                    distributor.setUpdateTime(TimeUtil.getCurrTime());
//
//                    userService.saveUser(userInfo);
//                    distributorService.saveDistributor(distributor);
//                    distributorPersonService.saveDistributorPerson(distributorPerson);
//                }
//
//            } else {
//
//            }
//
//            if (userList.get(0).getDistributorId() == null || userList.get(0).getDistributorId() == -1) {
//
//            }

            bizResp.setUserInfo(userInfo);
            bizResp.setResult_code(BusiError.ERR_CODE_SUCCESS);
            bizResp.setError_message("");
        } catch (Exception e) {
            logger.error("内部出错", e);
            bizResp.setResult_code(BusiError.ERR_CODE_DB_CONF);
            bizResp.setError_message(BusiError.ERR_MSG_DB_CONF);
        }
    }


    @Override
    public ValidateRet checkParam(AuthCodeToOpenIdReq req, AuthCodeToOpenIdResp resp) {
        ValidateRet vRet = super.checkParam(req, resp);
        if (!vRet.isValid()) return vRet;

        List<ValidateParam> paramList = new ArrayList<ValidateParam>();
        if (StringUtils.isEmpty(req.getOpenid()))
            paramList.add(new ValidateParam("Code", ValidateType.NOTBLANK, req.getCode()));
        vRet = ValidateUtil.validate(paramList);

        if (vRet == null) vRet = new ValidateRet(true, "");
        if (!vRet.isValid()) {
            resp.setResult_code(BusiError.ERR_CODE_PARAM_BAD_REQ);
            resp.setError_message(vRet.getErrMsg());
        }
        return vRet;
    }
}
